/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sandbox.patterns.quantity;

/**
 *
 * @author Saager Mhatre
 */
public class Quantity<U extends Unit<U>> {
    private double amount;
    private U unit;
    
    public Quantity(double amount, U unit) {
        if ( unit == null )
            throw new NullPointerException("Cannot create quantity with null Unit");

        this.amount = amount;
        this.unit = unit;
    }
    
    public Quantity<U> to(U otherUnit) {
        return this.unit == otherUnit ?
            new Quantity<U>(amount, otherUnit) :
            new Quantity<U>(otherUnit.from(amount, this.unit), otherUnit);
    }

    @Override
    public String toString() {
        return "" + amount + " " + unit.getName() + "s";
    }

    @Override
    public boolean equals(Object other) {
        if ( other == null || other.getClass() != this.getClass() ) return false;
        
        @SuppressWarnings(value="unchecked")
        Quantity<U> otherQty = (Quantity<U>) other;
        return unit.getClass() != otherQty.unit.getClass()?
                false :
                otherQty.unit == this.unit ? otherQty.amount == this.amount : equals(otherQty.to(unit));
    }

    @Override
    public int hashCode() {
        int hash = 3;
        final long amountToLongBits = Double.doubleToLongBits(this.amount);
        hash = 83 * hash + (int) (amountToLongBits ^ (amountToLongBits >>> 32));
        hash = 83 * hash + this.unit.hashCode();
        return hash;
    }
    
}
